
%next(_,_,_,-1).
next(AbsState, PathInfo, Length, NewBitString) :-
    PathInfo =.. [path_info,_MethodNum, _InstrCount, BitString],
    %format('Path is ~w~n~n',PathInfo),


    %format('In next, Length = ~w~n', [Length]),
    Temp is (BitString /\ ((2^Length) - 1)),
    rev_n(Length,Temp,NewTemp),
    X is (NewTemp + 1),
    
    Y is 2^Length,
    format('X is ~w, Length is ~w, Y is ~w~n~n',[X, Length, Y]),
    ((X >= Y) ->
	    writeln('next DOES NOT exist'),
	    NewBitString is -1;
	    %    rev_n(Length,NewBitString1,NewBitString);
	    writeln('next EXISTS'),
	    rev_n(Length,X,NewX),
	    NewBitString is NewX),
	    
    format('OldBitString = ~w, NewBitString is ~w--------->~n', [BitString,NewBitString]). 

% Helper functions for next/4:
help_revbits(_Bits,_Count,0,InitNewBits,InitNewBits). 
help_revbits(Bits,Count,InsertCount,InitNewBits, NewBits) :-
	% Count is the current marker - we start with 1
	count_bits(InitNewBits,FullBitCount),
	NewBitCount is (FullBitCount-1),
	InsertCount > 0,

	% Get the (Count)th bit of Bits:
	X is ((Bits /\ (2^(Count-1))) >> (Count-1)),

	% find the correct position to insert that bit
	NewX is (X << (InsertCount-1)),

	% or it with the accumulated string 
	TempBits is (InitNewBits \/ NewX),
	
	NewCount is (Count + 1),
	NewInsertCount is InsertCount - 1,
	help_revbits(Bits, NewCount,NewInsertCount,TempBits,NewBits).

rev_bits(Bits, FinalReversedBits) :-

	count_bits(Bits,BitCount),

	
	%	M is (1 << (BitCount-1)),
	N is (2^(BitCount-1)),
	help_revbits(Bits,1,(BitCount-1),N,ReversedBits),

	

	% format('BitCount = ~w, ReversedBits = ~w~n',[BitCount,ReversedBits]),
	
	% remove the leading one before returning.
	FinalReversedBits is (ReversedBits - (2^(BitCount-1))).

help_count_bits(Z,Count,Count) :-
	%popcount gives the # of 1s in the bitstring Z
	Ones is popcount(Z),
	Ones is 0.
help_count_bits(Z,OldCount,NewCount) :-
	Ones is popcount(Z),
	Ones > 0,
	NewZ is (Z >> 1),
	TempCount is (OldCount + 1),
	help_count_bits(NewZ,TempCount,NewCount).

count_bits(Bits,Count) :- help_count_bits(Bits,0,Count).


rev_n(N,Z,NewZ) :-
    Mask is ((2 ^ N) - 1),
    LowestBits is (Z /\ Mask),

    %Add a leading one before passing onto revbits. 
    NewLowestBits is ((2^N) \/ LowestBits),
    rev_bits(NewLowestBits, RevLowestBits),

    % format('RevLowestBits =~w~n', [RevLowestBits]),
    
    count_bits(Z,BitCount),
    X is ((2^BitCount)-1),
    Y is (X - Mask),
    FlippedMask is (X /\ Y),

    writeln(FlippedMask),

    ZTopBits is (FlippedMask /\ Z),

    NewZ is (ZTopBits \/ RevLowestBits).
    % format('LowestBits = ~w, ZTopBits = ~w, NewZ = ~w~n',[LowestBits,ZTopBits,NewZ]).



